#!/bin/bash

# Let's Encrypt SSL证书自动安装脚本 + Nginx优化
# 域名: wm.gvgmkt.com

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 检查root权限
check_root() {
    if [[ $EUID -ne 0 ]]; then
        log_error "此脚本必须以root权限运行"
        exit 1
    fi
}

# 优化Nginx主配置（Gzip和缓存）
optimize_nginx_main() {
    log_info "优化Nginx主配置（Gzip和缓存）..."
    
    # 备份原配置
    cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup
    
    # 创建优化的nginx.conf
    cat > /etc/nginx/nginx.conf <<'EOF'
user www-data;
worker_processes auto;
worker_cpu_affinity auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
    worker_connections 4096;
    multi_accept on;
    use epoll;
}

http {
    # 基础设置
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 30;
    keepalive_requests 1000;
    reset_timedout_connection on;
    client_body_timeout 15;
    client_header_timeout 15;
    send_timeout 15;
    
    # 限制缓冲区大小
    client_body_buffer_size 128K;
    client_header_buffer_size 1k;
    client_max_body_size 100m;
    large_client_header_buffers 4 4k;
    
    # 文件缓存
    open_file_cache max=200000 inactive=20s;
    open_file_cache_valid 60s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;
    
    types_hash_max_size 2048;
    server_tokens off;
    
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    # 日志格式
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for" '
                    '$request_time $upstream_response_time';
    
    access_log /var/log/nginx/access.log main buffer=64k flush=1m;
    error_log /var/log/nginx/error.log warn;

    # Gzip压缩配置
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_min_length 1024;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/json
        application/javascript
        application/xml+rss
        application/atom+xml
        image/svg+xml
        font/woff
        font/woff2
        application/vnd.ms-fontobject
        application/x-font-ttf;

    # 代理缓存路径（可选，用于反向代理）
    # proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g 
    #                 inactive=60m use_temp_path=off;

    # 包含其他配置
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}
EOF

    # 创建缓存目录
    mkdir -p /var/cache/nginx
    chown -R www-data:www-data /var/cache/nginx
    
    log_success "Nginx主配置优化完成"
}

# 检查域名解析
check_dns() {
    log_info "检查域名解析..."
    local domain="$1"
    
    # 获取服务器IP
    SERVER_IP=$(curl -s icanhazip.com 2>/dev/null || hostname -I | awk '{print $1}')
    
    log_info "服务器IP: $SERVER_IP"
    log_info "检查域名 $domain 的DNS解析..."
    
    # 检查A记录
    DOMAIN_IP=$(dig +short A "$domain")
    if [[ -n "$DOMAIN_IP" ]]; then
        log_info "域名 $domain 解析到: $DOMAIN_IP"
        if [[ "$DOMAIN_IP" == "$SERVER_IP" ]]; then
            log_success "域名解析正确"
        else
            log_warning "域名解析IP与服务器IP不匹配"
        fi
    else
        log_warning "无法获取域名解析信息"
    fi
    
    read -p "是否继续? (y/n): " -n 1 -r
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        exit 1
    fi
}

# 安装Certbot
install_certbot() {
    log_info "安装Certbot..."
    
    # 更新系统
    apt update
    
    # 安装Certbot和Nginx插件
    apt install -y certbot python3-certbot-nginx
    
    # 验证安装
    if certbot --version &> /dev/null; then
        log_success "Certbot安装成功"
    else
        log_error "Certbot安装失败"
        exit 1
    fi
}

# 配置Nginx HTTP（用于证书验证）
setup_nginx_http() {
    log_info "配置Nginx HTTP..."
    
    local domain="$1"
    
    # 创建HTTP配置
    cat > /etc/nginx/sites-available/"$domain" <<EOF
server {
    listen 80;
    server_name $domain;
    
    root /var/www/html/wordpress;
    index index.php index.html index.htm;

    # Gzip压缩（继承主配置）
    gzip_static on;

    # 缓存头
    add_header Cache-Control "public, must-revalidate";
    add_header X-Powered-By "WordPress";

    # ACME挑战目录（Let's Encrypt验证）
    location ~ /\.well-known/acme-challenge {
        allow all;
        root /var/www/certbot;
        access_log off;
        log_not_found off;
    }

    # 静态文件缓存
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|webp|woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
        add_header Vary "Accept-Encoding";
        access_log off;
        log_not_found off;
    }

    # 暂时不重定向，等证书获取后再启用HTTPS重定向
    location / {
        try_files \$uri \$uri/ /index.php?\$args;
        add_header X-Content-Type-Options "nosniff";
        add_header X-Frame-Options "SAMEORIGIN";
    }

    # PHP处理
    location ~ \.php\$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.4-fpm.sock;
        fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
        include fastcgi_params;
        
        # 缓存和性能
        fastcgi_buffer_size 128k;
        fastcgi_buffers 256 16k;
        fastcgi_busy_buffers_size 256k;
        fastcgi_temp_file_write_size 256k;
        fastcgi_read_timeout 300;
    }

    # 禁止访问敏感文件
    location ~* (wp-config\.php|readme\.html|license\.txt|error_log) {
        deny all;
        access_log off;
        log_not_found off;
    }

    # 隐藏目录列表
    location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
    }

    location ~ /\.ht {
        deny all;
    }

    access_log /var/log/nginx/${domain}_access.log main buffer=64k flush=1m;
    error_log /var/log/nginx/${domain}_error.log warn;
}
EOF

    # 启用站点
    ln -sf /etc/nginx/sites-available/"$domain" /etc/nginx/sites-enabled/
    
    # 创建证书验证目录
    mkdir -p /var/www/certbot
    
    # 测试配置
    nginx -t
    
    # 重载Nginx
    systemctl reload nginx
    
    log_success "Nginx HTTP配置完成"
}

# 获取SSL证书（只为主域名）
obtain_ssl_certificate() {
    log_info "获取SSL证书（仅主域名）..."
    
    local domain="$1"
    local email="$2"
    
    log_info "停止Nginx以释放80端口..."
    systemctl stop nginx
    
    # 等待确保Nginx完全停止
    sleep 3
    
    # 检查80端口是否被占用
    if netstat -tulpn | grep :80 > /dev/null; then
        log_error "80端口仍被占用，请手动解决冲突"
        systemctl start nginx
        exit 1
    fi
    
    # 获取证书（仅主域名，使用standalone模式）
    log_info "开始获取证书..."
    if certbot certonly --standalone -d "$domain" \
        --email "$email" --agree-tos --non-interactive; then
        log_success "SSL证书获取成功"
    else
        log_error "SSL证书获取失败"
        log_info "重新启动Nginx..."
        systemctl start nginx
        exit 1
    fi
    
    # 重新启动Nginx
    log_info "重新启动Nginx..."
    systemctl start nginx
    
    # 等待Nginx启动
    sleep 2
}

# 配置Nginx HTTPS（包含Gzip和缓存优化）
setup_nginx_https() {
    log_info "配置Nginx HTTPS（包含Gzip和缓存优化）..."
    
    local domain="$1"
    
    # 创建HTTPS配置
    cat > /etc/nginx/sites-available/"$domain-ssl" <<EOF
server {
    listen 443 ssl http2;
    server_name $domain;
    
    root /var/www/html/wordpress;
    index index.php index.html index.htm;

    # SSL证书配置
    ssl_certificate /etc/letsencrypt/live/$domain/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/$domain/privkey.pem;
    
    # SSL安全配置
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:50m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;
    ssl_stapling on;
    ssl_stapling_verify on;
    
    # 安全头部
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;

    # Gzip压缩
    gzip_static on;

    # WordPress配置
    location / {
        try_files \$uri \$uri/ /index.php?\$args;
        add_header Cache-Control "no-cache, must-revalidate";
    }

    # PHP处理
    location ~ \.php\$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.4-fpm.sock;
        fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
        include fastcgi_params;
        
        # 性能优化
        fastcgi_buffer_size 128k;
        fastcgi_buffers 256 16k;
        fastcgi_busy_buffers_size 256k;
        fastcgi_temp_file_write_size 256k;
        fastcgi_read_timeout 300;
        
        # 安全设置
        fastcgi_hide_header X-Powered-By;
    }

    # ACME挑战目录
    location ~ /\.well-known/acme-challenge {
        allow all;
        root /var/www/certbot;
        access_log off;
        log_not_found off;
    }

    # 静态文件缓存 - 图片、字体、CSS、JS
    location ~* \.(jpg|jpeg|png|gif|ico|svg|webp)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
        add_header Vary "Accept-Encoding";
        access_log off;
        log_not_found off;
    }
    
    location ~* \.(css|js)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
        add_header Vary "Accept-Encoding";
        access_log off;
        log_not_found off;
    }
    
    location ~* \.(woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
        add_header Vary "Accept-Encoding";
        access_log off;
        log_not_found off;
    }

    # HTML文件缓存
    location ~* \.(html|htm)$ {
        expires 1h;
        add_header Cache-Control "public, must-revalidate";
        add_header Vary "Accept-Encoding";
    }

    # 禁止访问隐藏文件
    location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
    }

    location ~ /\.ht {
        deny all;
    }

    # 禁止访问敏感文件
    location ~* (wp-config\.php|readme\.html|license\.txt|error_log) {
        deny all;
        access_log off;
        log_not_found off;
    }

    access_log /var/log/nginx/${domain}_ssl_access.log main buffer=64k flush=1m;
    error_log /var/log/nginx/${domain}_ssl_error.log warn;
}

# HTTP重定向到HTTPS
server {
    listen 80;
    server_name $domain;
    
    # ACME挑战目录（证书续期需要）
    location ~ /\.well-known/acme-challenge {
        allow all;
        root /var/www/certbot;
        access_log off;
        log_not_found off;
    }
    
    # 重定向到HTTPS
    location / {
        return 301 https://\$server_name\$request_uri;
    }
    
    access_log /var/log/nginx/${domain}_redirect.log main buffer=32k flush=1m;
}
EOF

    # 启用HTTPS配置
    ln -sf /etc/nginx/sites-available/"$domain-ssl" /etc/nginx/sites-enabled/
    
    # 禁用旧的HTTP配置
    rm -f /etc/nginx/sites-enabled/"$domain"
    
    # 测试配置
    nginx -t
    
    # 重载Nginx
    systemctl reload nginx
    
    log_success "Nginx HTTPS配置完成"
}

# 设置自动续期
setup_auto_renewal() {
    log_info "设置证书自动续期..."
    
    # 测试续期
    if certbot renew --dry-run; then
        log_success "自动续期测试成功"
    else
        log_warning "自动续期测试失败，请手动检查"
    fi
    
    # 添加定时任务
    (crontab -l 2>/dev/null; echo "0 3 * * * /usr/bin/certbot renew --quiet --post-hook \"systemctl reload nginx\"") | crontab -
    
    log_success "自动续期已设置"
}

# 测试Gzip和缓存
test_gzip_cache() {
    log_info "测试Gzip压缩和缓存..."
    
    local domain="$1"
    
    # 测试Gzip
    if curl -H "Accept-Encoding: gzip" -I "https://$domain/wp-includes/js/jquery/jquery.js" 2>/dev/null | grep -i "gzip" > /dev/null; then
        log_success "Gzip压缩工作正常"
    else
        log_warning "Gzip压缩可能未正常工作"
    fi
    
    # 测试缓存头
    if curl -I "https://$domain/wp-content/themes/twentytwentyfour/style.css" 2>/dev/null | grep -i "cache-control" > /dev/null; then
        log_success "缓存头设置正常"
    else
        log_warning "缓存头可能未正确设置"
    fi
}

# 显示优化摘要
show_optimization_summary() {
    log_success "=== Nginx优化配置完成 ==="
    echo ""
    echo "已启用的优化功能:"
    echo "✓ Gzip压缩 - 减少传输大小"
    echo "✓ 静态文件缓存 - 提高加载速度"
    echo "✓ HTTP/2 - 多路复用"
    echo "✓ SSL优化 - 安全连接"
    echo "✓ 文件缓存 - 减少IO操作"
    echo "✓ 安全头部 - 增强安全性"
    echo ""
    echo "缓存策略:"
    echo "  - 图片/CSS/JS: 1年缓存"
    echo "  - 字体文件: 1年缓存"
    echo "  - HTML文件: 1小时缓存"
    echo "  - 动态内容: 不缓存"
    echo ""
    echo "Gzip压缩类型:"
    echo "  - 文本文件 (HTML, CSS, JS, XML)"
    echo "  - JSON数据"
    echo "  - 字体文件"
    echo "  - SVG图片"
    echo ""
}

# 主安装函数
main() {
    local domain="wm.gvgmkt.com"
    local email="admin@$domain"
    
    check_root
    
    log_info "开始为域名 $domain 安装SSL证书和优化Nginx..."
    
    # 优化Nginx主配置
    optimize_nginx_main
    
    # 检查域名解析
    check_dns "$domain"
    
    # 安装Certbot
    install_certbot
    
    # 配置Nginx HTTP
    setup_nginx_http "$domain"
    
    # 获取SSL证书
    obtain_ssl_certificate "$domain" "$email"
    
    # 配置Nginx HTTPS
    setup_nginx_https "$domain"
    
    # 设置自动续期
    setup_auto_renewal
    
    # 测试优化功能
    test_gzip_cache "$domain"
    
    # 显示优化摘要
    show_optimization_summary
    
    log_success "安装完成！访问 https://$domain 测试网站"
}

# 执行主函数
main "$@"